home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / console / svgatext.3 / svgatext / SVGATextMode-1.3 / validate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-15  |  10.3 KB  |  325 lines

  1. /*  SVGATextMode -- An SVGA textmode manipulation/enhancement tool
  2.  *
  3.  *  Copyright (C) 1995,1996  Koen Gadeyne
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20.  
  21. /***
  22.  *** validate.c, mode validation functions
  23.  ***/
  24.  
  25. /*
  26.  * If defined, CHECK_NUMCLOCKS will check if the number of clocks in the Clocks line
  27.  * corresponds to the number that SVGATextMode expects. This is more of a hassle than an advantage,,,
  28.  */
  29. #define CHECK_NUMCLOCKS
  30.    
  31.  
  32. #include "misc.h"
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <unistd.h>
  38. #include <math.h>
  39.  
  40. #include "validate.h"
  41. #include "cfg_structs.h"
  42. #include "setclock.h"
  43. #include "messages.h"
  44. #include "chipset.h"
  45.  
  46.  
  47. void sanitize_cfgfile_data()
  48. {
  49.   if (chipset<0) PERROR(("No chipset defined in config file\n"));
  50.   if (!h_mon_limits) addhsync(DEFLT_HSYNC_MIN, DEFLT_HSYNC_MAX);
  51.   if (!v_mon_limits) addvsync(DEFLT_VSYNC_MIN, DEFLT_VSYNC_MAX);
  52.   if ((clock_data.num_clocks==0) && (clock_data.clockchiptype==CLKCHIP_NONE) && (!clock_data.ck_prog_path))
  53.     PERROR(("No Clocks line, no ClockChip and no ClockProg defined in config file. Make up your mind.\n"));
  54.   if ((clock_data.num_clocks!=0) && (clock_data.clockchiptype!=CLKCHIP_NONE))
  55.     PERROR(("Both ClockChip _and_ a Clocks line defined in config file. Make up your mind.\n"));
  56.   if (clock_data.mclk!=MCLK_NOT_DEFINED)
  57.     switch(clock_data.clockchiptype)
  58.     {
  59.       case CLKCHIP_S3_SDAC:
  60.       case CLKCHIP_S3GENDAC:
  61.       case CLKCHIP_ICS5300:
  62.       case CLKCHIP_ICS5342:
  63.       case CLKCHIP_ICS5341: break;  /* these chips support clockchip programming */
  64.       default:
  65.                PERROR(("MClk programming not supported on selected chipset/clockchip combination\n"));
  66.     }
  67.   if ((clock_data.clockchiptype==CLKCHIP_IBMRGB5XX) && (clock_data.refclk==REFCLK_NOT_DEFINED))
  68.     PERROR(("S3 cards with IBM RGB RAMDAC must have RefClk defined in config file.\n"));
  69.   if ( ( !(clock_data.clockchiptype==CLKCHIP_TI3026) && !(clock_data.clockchiptype==CLKCHIP_TI3025) )
  70.        && (OFLG_ISSET(OPT_SOG)) )
  71.     PERROR(("The S3 `sync_on_green' option is only allowed for TI302X RAMDAC's\n"));
  72.  
  73. #ifdef CHECK_NUMCLOCKS  
  74.    /*
  75.     * check for correct amount of clocks, if possible for the specified chip set. This could be incorrect...
  76.     */
  77.  
  78. #define CHECKCLK(nclk) \
  79.     if ( clock_data.num_clocks != (nclk) ) \
  80.       PWARNING(("`%s' chipset normally has %d clocks (currently %d defined).\n",\
  81.                  ChipsetRec[(chipset)].name_str, (nclk), clock_data.num_clocks))
  82.                  
  83.     switch (chipset)      
  84.     {
  85.       /* first, the exceptions */
  86.       case CS_VGA:
  87.         if (clock_data.num_clocks > 4)
  88.           PWARNING(("Generic VGA chipsets can have no more than 4 clocks (currently %d defined).\n", clock_data.num_clocks));
  89.         break;
  90.       case CS_S3: 
  91.         if ((clock_data.num_clocks>0) && (clock_data.num_clocks != 16))
  92.           PWARNING(("`S3' chipsets (without clockchip) normally have 16 clocks (currently %d defined).\n", clock_data.num_clocks));
  93.         break;
  94.       case CS_PVGA1:
  95.         if ((clock_data.num_clocks != 8) && (clock_data.num_clocks != 4))
  96.           PWARNING(("`PVGA1' chipset must have 4 or 8 clocks in 'clocks' line (currently %d defined).\n", clock_data.num_clocks));
  97.         break;
  98.       /* generic cases */
  99.       case CS_WDC90C0X:
  100.         CHECKCLK( 9);
  101.         break;
  102.       case CS_WDC90C1X:
  103.         CHECKCLK( 9);
  104.         break;
  105.       case CS_WDC90C2X:
  106.         CHECKCLK( 9);
  107.         break;
  108.       case CS_WDC90C3X:
  109.         CHECKCLK(17);
  110.         break;
  111.       case CS_ATIMACH32:
  112.         CHECKCLK(32);
  113.         break;
  114.       case CS_ATI:
  115.         CHECKCLK(64);
  116.         break;
  117.       case CS_ALI:
  118.         CHECKCLK(16);
  119.         break;
  120.       case CS_AL2101:
  121.         CHECKCLK( 8);
  122.         break;
  123.       case CS_OTI67:
  124.         CHECKCLK( 8);
  125.         break;
  126.       case CS_OTI77:
  127.         CHECKCLK( 8);
  128.         break;
  129.       case CS_OTI87:
  130.         CHECKCLK(16);
  131.         break;
  132.       case CS_SIS:
  133.         CHECKCLK(16);
  134.         break;
  135.       case CS_REALTEK:
  136.         CHECKCLK(16);
  137.         break;
  138.       case CS_ARK:
  139.         CHECKCLK(16);
  140.         break;
  141.       case CS_GVGA:
  142.         CHECKCLK(8);
  143.         break;
  144.       case CS_NCR22E:
  145.         CHECKCLK( 8);
  146.         break;
  147.       case CS_NCR32:
  148.         CHECKCLK(16);
  149.         break;
  150.       case CS_MX:
  151.         CHECKCLK( 8);
  152.         break;
  153.       case CS_ET3000:
  154.         CHECKCLK( 8);
  155.         break;
  156.     }
  157. #endif         
  158.  
  159. }
  160.  
  161. bool check_range(int checkval, t_mon_timing *p_tim)
  162. {
  163.   bool range_ok=FALSE;
  164.   t_mon_timing *curr_tim = p_tim;
  165.   
  166.   while ((curr_tim) && (!range_ok))
  167.   {
  168.     range_ok = ((checkval >= curr_tim->low_limit) && (checkval <= curr_tim->high_limit));
  169.     PDEBUG(("Check_range(%d): range from %d to %d %s\n", checkval, curr_tim->low_limit, curr_tim->high_limit, (range_ok==TRUE) ? "OK" : "failed"));
  170.     curr_tim = curr_tim->next;
  171.   }
  172.   return(range_ok);
  173. }
  174.  
  175.  
  176. bool validate_clock(int req_clock, int report_error)
  177. {
  178.   int temp;  
  179.   bool clock_valid=TRUE;
  180.   int realclock;
  181.  
  182.   /* find closest clock */
  183.   if (GetClock(chipset, req_clock, &realclock, report_error) < 0)
  184.     return(FALSE);
  185.  
  186.   /* calculate deviation from requested clock */
  187.   temp = abs(realclock-req_clock);
  188.  
  189.   if( temp > MAX_CLOCKDEVIATION )
  190.   {
  191.     clock_valid=FALSE;
  192.     if (report_error)
  193.     {
  194.       if ((req_clock < 25000) && (!OFLG_ISSET(OPT_CLOCKDIV2)))
  195.         PWARNING(("Selected clock is below standard VGA clocks, and is not available in 'clocks' line.\n\
  196.                    UNLESS you enable division by 2 (Option 'ClockDiv2')\n"));
  197.       PERROR(("The closest available clock %.2f differs too much (max = %.1f) from specified clock %.2f\n",\
  198.                realclock/1000.0, MAX_CLOCKDEVIATION/1000.0, req_clock/1000.0));
  199.     }
  200.   }
  201.   PDEBUG(("Clock deviation (from requested clock) = |%d-%d|=%d kHz (%1.2f%%).\n",
  202.            req_clock, realclock, temp, (temp*100.0)/req_clock));
  203.  
  204.   return(clock_valid);
  205. }
  206.  
  207.  
  208. /*
  209.  * validate the mode line, using H/V freq limits, clock definitions and max clock
  210.  * abort with error message or just return error code depending on "report_error" flag
  211.  * Also check if the required clock (or a close match) is available from clock generator.
  212.  */
  213.  
  214.  
  215. int validate_mode(t_mode *mode, bool report_error)
  216. {
  217.   bool mode_valid = TRUE;
  218.   int max_clock;
  219.  
  220.  /*
  221.   * Check VGA chip clock speed limit.
  222.   */
  223.  
  224.   max_clock = (clock_data.maxclock * mode->FontWidth)/8;
  225.    
  226.   if ( mode->pixelClock > max_clock )
  227.   {
  228.     mode_valid=FALSE;
  229.     PDEBUG(("Check clock speed: Too high\n"));
  230.     if (report_error)
  231.       PERROR(("Pixel Clock (%.2f MHz) too high for this chipset\n"\
  232.               "  max pixel clock = %.2f/%.2f MHz for 8/9 pixel wide font resp.\n",\
  233.                mode->pixelClock/1000.0, clock_data.maxclock/1000.0, clock_data.maxclock*9/8000.0));
  234.   }
  235.   else PDEBUG(("Check max clock speed: OK\n"));
  236.  
  237.  /*
  238.   * Check clock generator limits.
  239.   */
  240.  
  241.   if (clock_data.clockchiptype == CLKCHIP_NONE)
  242.   {
  243.     if (!validate_clock(mode->pixelClock, report_error)) mode_valid=FALSE;
  244.   }
  245.   else
  246.   {
  247.     if (mode->pixelClock < ClockchipData[clock_data.clockchiptype].minclock)
  248.     {
  249.       PDEBUG(("Check Clockchip speed: too low\n"));
  250.       if (report_error)
  251.         PERROR(("Selected clockchip (%s) cannot produce requested clock of %.2f MHz (min = %.2f)\n",\
  252.                  ClockchipRec[clock_data.clockchiptype].name_str,\
  253.                  mode->pixelClock/1000.0,\
  254.                  ClockchipData[clock_data.clockchiptype].minclock/1000.0));
  255.       else
  256.         mode_valid=FALSE;
  257.     }
  258.     if (mode->pixelClock > ClockchipData[clock_data.clockchiptype].maxclock)
  259.     {
  260.       PDEBUG(("Check Clockchip speed: too high\n"));
  261.       if (report_error)
  262.         PERROR(("Selected clockchip (%s) cannot produce requested clock of %.2f MHz (max = %.2f)\n",\
  263.                  ClockchipRec[clock_data.clockchiptype].name_str,\
  264.                  mode->pixelClock/1000.0,\
  265.                  ClockchipData[clock_data.clockchiptype].maxclock/1000.0));
  266.       else 
  267.         mode_valid=FALSE;
  268.     }
  269.   }
  270.  
  271.  /*
  272.   * Check monitor H/V freq limits.
  273.   */
  274.  
  275.   if (!check_range(mode->hfreq, h_mon_limits)) 
  276.   {
  277.     mode_valid=FALSE;
  278.     if (report_error) PERROR(("Horizontal Sync Frequency (%.2fkHz) out of range.\n", mode->hfreq/1000.0));
  279.   }
  280.   if (!check_range(mode->vfreq, v_mon_limits))
  281.   {
  282.     mode_valid=FALSE;
  283.     if (report_error) PERROR(("Vertical Refresh Frequency (%.2fHz) out of range.\n", mode->vfreq/1000.0));
  284.   }
  285.   return(mode_valid);
  286. }
  287.  
  288.  
  289. void scan_valid_modes(int validate)
  290. {
  291.   t_mode *curr_textmode;
  292.  
  293.   PDEBUG(("Scanning for valid Text Mode lines\n"));
  294.  
  295.   curr_textmode = text_mode_list;
  296.   while (curr_textmode)
  297.   {
  298.     if ((!validate) || validate_mode(curr_textmode, FALSE))
  299.     {
  300.       printf("%s  Clock: %.2fMHz  Size: %dx%d  CharCell: %dx%d%s  Refresh: %.2fkHz/%.1fHz\n",
  301.               curr_textmode->name, curr_textmode->pixelClock/1000.0,
  302.               curr_textmode->cols, curr_textmode->rows,
  303.               curr_textmode->FontWidth, curr_textmode->FontHeight,
  304.               MOFLG_ISSET(curr_textmode,ATTR_DOUBLESCAN) ? "D" : "", curr_textmode->hfreq/1000.0, curr_textmode->vfreq/1000.0);
  305.     }
  306.     curr_textmode = curr_textmode->next;
  307.   }
  308. }
  309.  
  310. void check_and_show_mode(t_mode* p_mode, int checkit)
  311. {
  312.  /*
  313.   * First show what mode would be programmed.
  314.   */
  315.   printf("Chipset = `%s', Textmode clock = %.2f MHz, %dx%d chars, CharCell = %dx%d%s. Refresh = %3.2fkHz/%3.1fHz.\n",
  316.           ChipsetRec[chipset].name_str,p_mode->pixelClock/1000.0,p_mode->cols,p_mode->rows,
  317.           p_mode->FontWidth, p_mode->FontHeight,MOFLG_ISSET(p_mode,ATTR_DOUBLESCAN) ? "D" : "",
  318.           p_mode->hfreq/1000.0,p_mode->vfreq/1000.0);
  319.  /*
  320.   * Now we should do some checking to see if the horizontal and vertical refresh frequencies are within limits
  321.   * Don't do this when we will not be programming the hardware, so you can check a mode's frequencies with "-n".
  322.   */
  323.   if (checkit) validate_mode(p_mode, TRUE);
  324. }
  325.